/** * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. * * You are hereby granted a non-exclusive, worldwide, royalty-free license to use, * copy, modify, and distribute this software in source code or binary form for use * in connection with the web services and APIs provided by Facebook. * * As with any software that integrates with the Facebook platform, your use of * this software is subject to the Facebook Developer Principles and Policies * [http://developers.facebook.com/policy/]. This copyright notice shall be * included in all copies or substantial portions of the software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package com.facebook; import android.graphics.Bitmap; import android.location.Location; import android.os.Bundle; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import com.facebook.share.internal.ShareInternalUtility; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class RequestTests extends FacebookTestCase { private final static String TEST_OG_TYPE = "facebooksdktests:test"; protected String[] getDefaultPermissions() { return new String[] { "email", "publish_actions", "read_stream" }; }; @MediumTest @LargeTest public void testExecuteSingleGet() { final AccessToken accessToken = getAccessTokenForSharedUser(); GraphRequest request = new GraphRequest(accessToken, "TourEiffel"); GraphResponse response = request.executeAndWait(); assertTrue(response != null); assertTrue(response.getError() == null); assertNotNull(response.getJSONObject()); assertNotNull(response.getRawResponse()); JSONObject graphPlace = response.getJSONObject(); assertEquals("Paris", graphPlace.optJSONObject("location").optString("city")); } @LargeTest public void testBuildsUploadPhotoHttpURLConnection() throws Exception { final AccessToken accessToken = getAccessTokenForSharedUser(); Bitmap image = createTestBitmap(128); GraphRequest request = ShareInternalUtility.newUploadPhotoRequest(accessToken, image, null); HttpURLConnection connection = GraphRequest.toHttpConnection(request); assertTrue(connection != null); assertNotSame("gzip", connection.getRequestProperty("Content-Encoding")); assertNotSame("application/x-www-form-urlencoded", connection.getRequestProperty("Content-Type")); } @LargeTest public void testBuildsUploadVideoHttpURLConnection() throws IOException, URISyntaxException { File tempFile = null; try { final AccessToken accessToken = getAccessTokenForSharedUser(); tempFile = createTempFileFromAsset("DarkScreen.mov"); GraphRequest request = ShareInternalUtility.newUploadVideoRequest( accessToken, tempFile, null); HttpURLConnection connection = GraphRequest.toHttpConnection(request); assertTrue(connection != null); assertNotSame("gzip", connection.getRequestProperty("Content-Encoding")); assertNotSame("application/x-www-form-urlencoded", connection.getRequestProperty("Content-Type")); } catch (Exception ex) { return; } finally { if (tempFile != null) { tempFile.delete(); } } } @MediumTest @LargeTest public void testExecuteSingleGetUsingHttpURLConnection() throws IOException { final AccessToken accessToken = getAccessTokenForSharedUser(); GraphRequest request = new GraphRequest(accessToken, "TourEiffel"); HttpURLConnection connection = GraphRequest.toHttpConnection(request); assertEquals("gzip", connection.getRequestProperty("Content-Encoding")); assertEquals("application/x-www-form-urlencoded", connection.getRequestProperty("Content-Type")); List<GraphResponse> responses = GraphRequest.executeConnectionAndWait(connection, Arrays.asList(new GraphRequest[]{request})); assertNotNull(responses); assertEquals(1, responses.size()); GraphResponse response = responses.get(0); assertTrue(response != null); assertTrue(response.getError() == null); assertNotNull(response.getJSONObject()); assertNotNull(response.getRawResponse()); JSONObject graphPlace = response.getJSONObject(); assertEquals("Paris", graphPlace.optJSONObject("location").optString("city")); // Make sure calling code can still access HTTP headers and call disconnect themselves. int code = connection.getResponseCode(); assertEquals(200, code); assertTrue(connection.getHeaderFields().keySet().contains("Content-Type")); connection.disconnect(); } @MediumTest @LargeTest public void testFacebookErrorResponseCreatesError() { GraphRequest request = new GraphRequest(null, "somestringthatshouldneverbeavalidfobjectid"); GraphResponse response = request.executeAndWait(); assertTrue(response != null); FacebookRequestError error = response.getError(); assertNotNull(error); FacebookException exception = error.getException(); assertNotNull(exception); assertTrue(exception instanceof FacebookServiceException); assertNotNull(error.getErrorType()); assertTrue(error.getErrorCode() != FacebookRequestError.INVALID_ERROR_CODE); assertNotNull(error.getRequestResultBody()); } @MediumTest @LargeTest public void testRequestWithNoTokenFails() { GraphRequest request = new GraphRequest(null, "me"); GraphResponse response = request.executeAndWait(); assertNotNull(response.getError()); } @MediumTest @LargeTest public void testExecuteRequestMe() { final AccessToken accessToken = getAccessTokenForSharedUser(); GraphRequest request = GraphRequest.newMeRequest(accessToken, null); GraphResponse response = request.executeAndWait(); validateMeResponse(accessToken, response); } static void validateMeResponse(AccessToken accessToken, GraphResponse response) { assertNull(response.getError()); JSONObject me = response.getJSONObject(); assertNotNull(me); assertEquals(accessToken.getUserId(), me.optString("id")); assertNotNull(response.getRawResponse()); } @MediumTest @LargeTest public void testExecuteMyFriendsRequest() { final AccessToken accessToken = getAccessTokenForSharedUser(); GraphRequest request = GraphRequest.newMyFriendsRequest(accessToken, null); GraphResponse response = request.executeAndWait(); validateMyFriendsResponse(response); } static void validateMyFriendsResponse(GraphResponse response) { assertNotNull(response); assertNull(response.getError()); JSONObject graphResult = response.getJSONObject(); assertNotNull(graphResult); JSONArray results = graphResult.optJSONArray("data"); assertNotNull(results); assertNotNull(response.getRawResponse()); } @MediumTest @LargeTest public void testExecutePlaceRequestWithLocation() { final AccessToken accessToken = getAccessTokenForSharedUser(); Location location = new Location(""); location.setLatitude(47.6204); location.setLongitude(-122.3491); GraphRequest request = GraphRequest.newPlacesSearchRequest(accessToken, location, 5, 5, null, null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject graphResult = response.getJSONObject(); assertNotNull(graphResult); JSONArray results = graphResult.optJSONArray("data"); assertNotNull(results); assertNotNull(response.getRawResponse()); } @MediumTest @LargeTest public void testExecutePlaceRequestWithSearchText() { final AccessToken accessToken = getAccessTokenForSharedUser(); // Pass a distance without a location to ensure it is correctly ignored. GraphRequest request = GraphRequest.newPlacesSearchRequest(accessToken, null, 1000, 5, "Starbucks", null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject graphResult = response.getJSONObject(); assertNotNull(graphResult); JSONArray results = graphResult.optJSONArray("data"); assertNotNull(results); assertNotNull(response.getRawResponse()); } @MediumTest @LargeTest public void testExecutePlaceRequestWithLocationAndSearchText() { final AccessToken accessToken = getAccessTokenForSharedUser(); Location location = new Location(""); location.setLatitude(47.6204); location.setLongitude(-122.3491); GraphRequest request = GraphRequest.newPlacesSearchRequest(accessToken, location, 1000, 5, "Starbucks", null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject graphResult = response.getJSONObject(); assertNotNull(graphResult); JSONArray results = graphResult.optJSONArray("data"); assertNotNull(results); assertNotNull(response.getRawResponse()); } private String executePostOpenGraphRequest() { final AccessToken accessToken = getAccessTokenForSharedUser(); JSONObject data = new JSONObject(); try { data.put("a_property", "hello"); } catch (JSONException e) { throw new RuntimeException(e); } GraphRequest request = ShareInternalUtility.newPostOpenGraphObjectRequest( accessToken, TEST_OG_TYPE, "a title", "http://www.facebook.com", "http://www.facebook.com/zzzzzzzzzzzzzzzzzzz", "a description", data, null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject graphResult = response.getJSONObject(); assertNotNull(graphResult); assertNotNull(graphResult.optString("id")); assertNotNull(response.getRawResponse()); return (String) graphResult.optString("id"); } @LargeTest public void testExecutePostOpenGraphRequest() { executePostOpenGraphRequest(); } @LargeTest public void testDeleteObjectRequest() { String id = executePostOpenGraphRequest(); final AccessToken accessToken = getAccessTokenForSharedUser(); GraphRequest request = GraphRequest.newDeleteObjectRequest(accessToken, id, null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject result = response.getJSONObject(); assertNotNull(result); assertTrue(result.optBoolean(GraphResponse.SUCCESS_KEY)); assertNotNull(response.getRawResponse()); } @LargeTest public void testUpdateOpenGraphObjectRequest() throws JSONException { String id = executePostOpenGraphRequest(); JSONObject data = new JSONObject(); data.put("a_property", "goodbye"); final AccessToken accessToken = getAccessTokenForSharedUser(); GraphRequest request = ShareInternalUtility.newUpdateOpenGraphObjectRequest(accessToken, id, "another title", null, "http://www.facebook.com/aaaaaaaaaaaaaaaaa", "another description", data, null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject result = response.getJSONObject(); assertNotNull(result); assertNotNull(response.getRawResponse()); } @LargeTest public void testExecuteUploadPhoto() { final AccessToken accessToken = getAccessTokenForSharedUser(); Bitmap image = createTestBitmap(128); GraphRequest request = ShareInternalUtility.newUploadPhotoRequest(accessToken, image, null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject result = response.getJSONObject(); assertNotNull(result); assertNotNull(response.getRawResponse()); } @LargeTest public void testExecuteUploadPhotoViaFile() throws IOException { File outputFile = null; FileOutputStream outStream = null; try { final AccessToken accessToken = getAccessTokenForSharedUser(); Bitmap image = createTestBitmap(128); File outputDir = getActivity().getCacheDir(); // context being the Activity pointer outputFile = File.createTempFile("prefix", "extension", outputDir); outStream = new FileOutputStream(outputFile); image.compress(Bitmap.CompressFormat.PNG, 100, outStream); outStream.close(); outStream = null; GraphRequest request = ShareInternalUtility.newUploadPhotoRequest( accessToken, outputFile, null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject result = response.getJSONObject(); assertNotNull(result); assertNotNull(response.getRawResponse()); } finally { if (outStream != null) { outStream.close(); } if (outputFile != null) { outputFile.delete(); } } } @LargeTest public void testUploadVideoFile() throws IOException, URISyntaxException { File tempFile = null; try { final AccessToken accessToken = getAccessTokenForSharedUser(); tempFile = createTempFileFromAsset("DarkScreen.mov"); GraphRequest request = ShareInternalUtility.newUploadVideoRequest(accessToken, tempFile, null); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertNull(response.getError()); JSONObject result = response.getJSONObject(); assertNotNull(result); assertNotNull(response.getRawResponse()); } catch (Exception ex) { return; } finally { if (tempFile != null) { tempFile.delete(); } } } @LargeTest public void testPostStatusUpdate() { final AccessToken accessToken = getAccessTokenForSharedUser(); JSONObject statusUpdate = createStatusUpdate(""); JSONObject retrievedStatusUpdate = postGetAndAssert(accessToken, "me/feed", statusUpdate); assertEquals(statusUpdate.optString("message"), retrievedStatusUpdate.optString("message")); } @MediumTest @LargeTest public void testCallbackIsCalled() { GraphRequest request = new GraphRequest(null, "4"); final ArrayList<Boolean> calledBack = new ArrayList<Boolean>(); request.setCallback(new GraphRequest.Callback() { @Override public void onCompleted(GraphResponse response) { calledBack.add(true); } }); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertTrue(calledBack.size() == 1); } @MediumTest @LargeTest public void testOnProgressCallbackIsCalled() { Bitmap image = Bitmap.createBitmap(128, 128, Bitmap.Config.ALPHA_8); GraphRequest request = ShareInternalUtility.newUploadPhotoRequest(null, image, null); assertTrue(request != null); final ArrayList<Boolean> calledBack = new ArrayList<Boolean>(); request.setCallback(new GraphRequest.OnProgressCallback() { @Override public void onCompleted(GraphResponse response) { } @Override public void onProgress(long current, long max) { calledBack.add(true); } }); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertFalse(calledBack.isEmpty()); } @MediumTest @LargeTest public void testLastOnProgressCallbackIsCalledOnce() { Bitmap image = Bitmap.createBitmap(128, 128, Bitmap.Config.ALPHA_8); GraphRequest request = ShareInternalUtility.newUploadPhotoRequest(null, image, null); assertTrue(request != null); final ArrayList<Boolean> calledBack = new ArrayList<Boolean>(); request.setCallback(new GraphRequest.OnProgressCallback() { @Override public void onCompleted(GraphResponse response) { } @Override public void onProgress(long current, long max) { if (current == max) calledBack.add(true); else if (current > max) calledBack.clear(); } }); GraphResponse response = request.executeAndWait(); assertNotNull(response); assertEquals(1, calledBack.size()); } @MediumTest @LargeTest public void testBatchTimeoutIsApplied() { GraphRequest request = new GraphRequest(null, "me"); GraphRequestBatch batch = new GraphRequestBatch(request); // We assume 1 ms is short enough to fail batch.setTimeout(1); List<GraphResponse> responses = GraphRequest.executeBatchAndWait(batch); assertNotNull(responses); assertTrue(responses.size() == 1); GraphResponse response = responses.get(0); assertNotNull(response); assertNotNull(response.getError()); } @MediumTest @LargeTest public void testBatchTimeoutCantBeNegative() { try { GraphRequestBatch batch = new GraphRequestBatch(); batch.setTimeout(-1); fail(); } catch (IllegalArgumentException ex) { } } @MediumTest @LargeTest public void testCantUseComplexParameterInGetRequest() { final AccessToken accessToken = getAccessTokenForSharedUser(); Bundle parameters = new Bundle(); parameters.putShortArray("foo", new short[1]); GraphRequest request = new GraphRequest(accessToken, "me", parameters, HttpMethod.GET, new ExpectFailureCallback()); GraphResponse response = request.executeAndWait(); FacebookRequestError error = response.getError(); assertNotNull(error); FacebookException exception = error.getException(); assertNotNull(exception); assertTrue(exception.getMessage().contains("short[]")); } private final Location SEATTLE_LOCATION = new Location("") { { setLatitude(47.6097); setLongitude(-122.3331); } }; @LargeTest public void testPaging() { final AccessToken accessToken = getAccessTokenForSharedUser(); final List<JSONObject> returnedPlaces = new ArrayList<JSONObject>(); GraphRequest request = GraphRequest .newPlacesSearchRequest(accessToken, SEATTLE_LOCATION, 1000, 3, null, new GraphRequest.GraphJSONArrayCallback() { @Override public void onCompleted(JSONArray places, GraphResponse response) { if (places == null) { assertNotNull(places); } for (int i = 0; i < places.length(); ++i) { returnedPlaces.add(places.optJSONObject(i)); } } }); GraphResponse response = request.executeAndWait(); assertNull(response.getError()); assertNotNull(response.getJSONObject()); assertNotSame(0, returnedPlaces.size()); returnedPlaces.clear(); GraphRequest nextRequest = response.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT); assertNotNull(nextRequest); nextRequest.setCallback(request.getCallback()); response = nextRequest.executeAndWait(); assertNull(response.getError()); assertNotNull(response.getJSONObject()); assertNotSame(0, returnedPlaces.size()); returnedPlaces.clear(); GraphRequest previousRequest = response.getRequestForPagedResults(GraphResponse.PagingDirection.PREVIOUS); assertNotNull(previousRequest); previousRequest.setCallback(request.getCallback()); response = previousRequest.executeAndWait(); assertNull(response.getError()); assertNotNull(response.getJSONObject()); assertNotSame(0, returnedPlaces.size()); } }